import _extends from "@babel/runtime/helpers/esm/extends";
import Vue from 'vue';
import Popup from '../popup';
import Toast from '../toast';
import ImagePreview from '../image-preview';
import SkuHeader from './components/SkuHeader';
import SkuHeaderItem from './components/SkuHeaderItem';
import SkuRow from './components/SkuRow';
import SkuRowItem from './components/SkuRowItem';
import SkuRowPropItem from './components/SkuRowPropItem';
import SkuStepper from './components/SkuStepper';
import SkuMessages from './components/SkuMessages';
import SkuActions from './components/SkuActions';
import {createNamespace, isDef} from '../utils';
import {
    getSelectedProperties,
    getSelectedPropValues,
    getSelectedSkuValues,
    getSkuComb,
    isAllSelected,
    isSkuChoosable
} from './utils/skuHelper';
import {LIMIT_TYPE, UNSELECTED_SKU_VALUE_ID} from './constants';

var namespace = createNamespace('sku');
var createComponent = namespace[0],
    bem = namespace[1],
    t = namespace[2];
var QUOTA_LIMIT = LIMIT_TYPE.QUOTA_LIMIT;
export default createComponent({
    props: {
        sku: Object,
        priceTag: String,
        goods: Object,
        value: Boolean,
        buyText: String,
        goodsId: [Number, String],
        hideStock: Boolean,
        addCartText: String,
        stepperTitle: String,
        getContainer: Function,
        hideQuotaText: Boolean,
        hideSelectedText: Boolean,
        resetStepperOnHide: Boolean,
        customSkuValidator: Function,
        closeOnClickOverlay: Boolean,
        disableStepperInput: Boolean,
        safeAreaInsetBottom: Boolean,
        resetSelectedSkuOnHide: Boolean,
        properties: Array,
        quota: {
            type: Number,
            default: 0
        },
        quotaUsed: {
            type: Number,
            default: 0
        },
        startSaleNum: {
            type: Number,
            default: 1
        },
        initialSku: {
            type: Object,
            default: function _default() {
                return {};
            }
        },
        stockThreshold: {
            type: Number,
            default: 50
        },
        showSoldoutSku: {
            type: Boolean,
            default: true
        },
        showAddCartBtn: {
            type: Boolean,
            default: true
        },
        bodyOffsetTop: {
            type: Number,
            default: 200
        },
        messageConfig: {
            type: Object,
            default: function _default() {
                return {
                    placeholderMap: {},
                    uploadImg: function uploadImg() {
                        return Promise.resolve();
                    },
                    uploadMaxSize: 5
                };
            }
        },
        customStepperConfig: {
            type: Object,
            default: function _default() {
                return {};
            }
        }
    },
    data: function data() {
        return {
            selectedSku: {},
            selectedProp: {},
            selectedNum: 1,
            show: this.value
        };
    },
    watch: {
        show: function show(val) {
            this.$emit('input', val);

            if (!val) {
                this.$emit('sku-close', {
                    selectedSkuValues: this.selectedSkuValues,
                    selectedNum: this.selectedNum,
                    selectedSkuComb: this.selectedSkuComb
                });

                if (this.resetStepperOnHide) {
                    this.resetStepper();
                }

                if (this.resetSelectedSkuOnHide) {
                    this.resetSelectedSku();
                }
            }
        },
        value: function value(val) {
            this.show = val;
        },
        skuTree: 'resetSelectedSku',
        initialSku: function initialSku() {
            this.resetStepper();
            this.resetSelectedSku();
        }
    },
    computed: {
        skuGroupClass: function skuGroupClass() {
            return ['van-sku-group-container', {
                'van-sku-group-container--hide-soldout': !this.showSoldoutSku
            }];
        },
        bodyStyle: function bodyStyle() {
            if (this.$isServer) {
                return;
            } // header高度82px, sku actions高度50px，如果改动了样式自己传下bodyOffsetTop调整下


            var maxHeight = window.innerHeight - this.bodyOffsetTop;
            return {
                maxHeight: maxHeight + 'px'
            };
        },
        isSkuCombSelected: function isSkuCombSelected() {
            var _this = this;

            // SKU 未选完
            if (this.hasSku && !isAllSelected(this.skuTree, this.selectedSku)) {
                return false;
            } // 属性未全选


            if (this.propList.some(function (it) {
                return (_this.selectedProp[it.k_id] || []).length < 1;
            })) {
                return false;
            }

            return true;
        },
        isSkuEmpty: function isSkuEmpty() {
            return Object.keys(this.sku).length === 0;
        },
        hasSku: function hasSku() {
            return !this.sku.none_sku;
        },
        hasSkuOrAttr: function hasSkuOrAttr() {
            return this.hasSku || this.propList.length > 0;
        },
        selectedSkuComb: function selectedSkuComb() {
            var skuComb = null;

            if (this.isSkuCombSelected) {
                if (this.hasSku) {
                    skuComb = getSkuComb(this.sku.list, this.selectedSku);
                } else {
                    skuComb = {
                        id: this.sku.collection_id,
                        price: Math.round(this.sku.price * 100),
                        stock_num: this.sku.stock_num
                    };
                }

                if (skuComb) {
                    skuComb.properties = getSelectedProperties(this.propList, this.selectedProp);
                    skuComb.property_price = this.selectedPropValues.reduce(function (acc, cur) {
                        return acc + (cur.price || 0);
                    }, 0);
                }
            }

            return skuComb;
        },
        selectedSkuValues: function selectedSkuValues() {
            return getSelectedSkuValues(this.skuTree, this.selectedSku);
        },
        selectedPropValues: function selectedPropValues() {
            return getSelectedPropValues(this.propList, this.selectedProp);
        },
        price: function price() {
            if (this.selectedSkuComb) {
                return ((this.selectedSkuComb.price + this.selectedSkuComb.property_price) / 100).toFixed(2);
            } // sku.price是一个格式化好的价格区间


            return this.sku.price;
        },
        originPrice: function originPrice() {
            if (this.selectedSkuComb && this.selectedSkuComb.origin_price) {
                return ((this.selectedSkuComb.origin_price + this.selectedSkuComb.property_price) / 100).toFixed(2);
            }

            return this.sku.origin_price;
        },
        skuTree: function skuTree() {
            return this.sku.tree || [];
        },
        propList: function propList() {
            return this.properties || [];
        },
        imageList: function imageList() {
            var imageList = [this.goods.picture];

            if (this.skuTree.length > 0) {
                this.skuTree.forEach(function (treeItem) {
                    if (!treeItem.v) {
                        return;
                    }

                    treeItem.v.forEach(function (vItem) {
                        var img = vItem.previewImgUrl || vItem.imgUrl || vItem.img_url;

                        if (img) {
                            imageList.push(img);
                        }
                    });
                });
            }

            return imageList;
        },
        stock: function stock() {
            var stockNum = this.customStepperConfig.stockNum;

            if (stockNum !== undefined) {
                return stockNum;
            }

            if (this.selectedSkuComb) {
                return this.selectedSkuComb.stock_num;
            }

            return this.sku.stock_num;
        },
        stockText: function stockText() {
            var h = this.$createElement;
            var stockFormatter = this.customStepperConfig.stockFormatter;
            if (stockFormatter) return stockFormatter(this.stock);
            return [t('stock') + " ", h("span", {
                "class": bem('stock-num', {
                    highlight: this.stock < this.stockThreshold
                })
            }, [this.stock]), " " + t('stockUnit')];
        },
        selectedText: function selectedText() {
            var _this2 = this;

            if (this.selectedSkuComb) {
                var values = this.selectedSkuValues.concat(this.selectedPropValues);
                return t('selected') + " " + values.map(function (item) {
                    return item.name;
                }).join('；');
            }

            var unselectedSku = this.skuTree.filter(function (item) {
                return _this2.selectedSku[item.k_s] === UNSELECTED_SKU_VALUE_ID;
            }).map(function (item) {
                return item.k;
            });
            var unselectedProp = this.propList.filter(function (item) {
                return (_this2.selectedProp[item.k_id] || []).length < 1;
            }).map(function (item) {
                return item.k;
            });
            return t('select') + " " + unselectedSku.concat(unselectedProp).join('；');
        }
    },
    created: function created() {
        var skuEventBus = new Vue();
        this.skuEventBus = skuEventBus;
        skuEventBus.$on('sku:select', this.onSelect);
        skuEventBus.$on('sku:propSelect', this.onPropSelect);
        skuEventBus.$on('sku:numChange', this.onNumChange);
        skuEventBus.$on('sku:previewImage', this.onPreviewImage);
        skuEventBus.$on('sku:overLimit', this.onOverLimit);
        skuEventBus.$on('sku:stepperState', this.onStepperState);
        skuEventBus.$on('sku:addCart', this.onAddCart);
        skuEventBus.$on('sku:buy', this.onBuy);
        this.resetStepper();
        this.resetSelectedSku(); // 组件初始化后的钩子，抛出skuEventBus

        this.$emit('after-sku-create', skuEventBus);
    },
    methods: {
        resetStepper: function resetStepper() {
            var skuStepper = this.$refs.skuStepper;
            var selectedNum = this.initialSku.selectedNum;
            var num = isDef(selectedNum) ? selectedNum : this.startSaleNum; // 用来缓存不合法的情况

            this.stepperError = null;

            if (skuStepper) {
                skuStepper.setCurrentNum(num);
            } else {
                // 当首次加载（skuStepper 为空）时，传入数量如果不合法，可能会存在问题
                this.selectedNum = num;
            }
        },
        // @exposed-api
        resetSelectedSku: function resetSelectedSku() {
            var _this3 = this;

            this.selectedSku = {}; // 重置 selectedSku

            this.skuTree.forEach(function (item) {
                _this3.selectedSku[item.k_s] = _this3.initialSku[item.k_s] || UNSELECTED_SKU_VALUE_ID;
            }); // 只有一个 sku 规格值时默认选中

            this.skuTree.forEach(function (item) {
                var key = item.k_s;
                var valueId = item.v[0].id;

                if (item.v.length === 1 && isSkuChoosable(_this3.sku.list, _this3.selectedSku, {
                    key: key,
                    valueId: valueId
                })) {
                    _this3.selectedSku[key] = valueId;
                }
            });
            var skuValues = this.selectedSkuValues;

            if (skuValues.length > 0) {
                this.$nextTick(function () {
                    _this3.$emit('sku-selected', {
                        skuValue: skuValues[skuValues.length - 1],
                        selectedSku: _this3.selectedSku,
                        selectedSkuComb: _this3.selectedSkuComb
                    });
                });
            } // 重置商品属性


            this.selectedProp = {};
            var _this$initialSku$sele = this.initialSku.selectedProp,
                selectedProp = _this$initialSku$sele === void 0 ? {} : _this$initialSku$sele; // 只有一个属性值时，默认选中，且选中外部传入信息

            this.propList.forEach(function (item) {
                if (item.v && item.v.length === 1) {
                    _this3.selectedProp[item.k_id] = [item.v[0].id];
                } else if (selectedProp[item.k_id]) {
                    _this3.selectedProp[item.k_id] = selectedProp[item.k_id];
                }
            });
            var propValues = this.selectedPropValues;

            if (propValues.length > 0) {
                this.$emit('sku-prop-selected', {
                    propValue: propValues[propValues.length - 1],
                    selectedProp: this.selectedProp,
                    selectedSkuComb: this.selectedSkuComb
                });
            }
        },
        getSkuMessages: function getSkuMessages() {
            return this.$refs.skuMessages ? this.$refs.skuMessages.getMessages() : {};
        },
        getSkuCartMessages: function getSkuCartMessages() {
            return this.$refs.skuMessages ? this.$refs.skuMessages.getCartMessages() : {};
        },
        validateSkuMessages: function validateSkuMessages() {
            return this.$refs.skuMessages ? this.$refs.skuMessages.validateMessages() : '';
        },
        validateSku: function validateSku() {
            if (this.selectedNum === 0) {
                return t('unavailable');
            }

            if (this.isSkuCombSelected) {
                return this.validateSkuMessages();
            } // 自定义sku校验


            if (this.customSkuValidator) {
                var err = this.customSkuValidator(this);
                if (err) return err;
            }

            return t('selectSku');
        },
        onSelect: function onSelect(skuValue) {
            var _extends2, _extends3;

            // 点击已选中的sku时则取消选中
            this.selectedSku = this.selectedSku[skuValue.skuKeyStr] === skuValue.id ? _extends({}, this.selectedSku, (_extends2 = {}, _extends2[skuValue.skuKeyStr] = UNSELECTED_SKU_VALUE_ID, _extends2)) : _extends({}, this.selectedSku, (_extends3 = {}, _extends3[skuValue.skuKeyStr] = skuValue.id, _extends3));
            this.$emit('sku-selected', {
                skuValue: skuValue,
                selectedSku: this.selectedSku,
                selectedSkuComb: this.selectedSkuComb
            });
        },
        onPropSelect: function onPropSelect(propValue) {
            var _extends4;

            var arr = this.selectedProp[propValue.skuKeyStr] || [];
            var pos = arr.indexOf(propValue.id);

            if (pos > -1) {
                arr.splice(pos, 1);
            } else if (propValue.multiple) {
                arr.push(propValue.id);
            } else {
                arr.splice(0, 1, propValue.id);
            }

            this.selectedProp = _extends({}, this.selectedProp, (_extends4 = {}, _extends4[propValue.skuKeyStr] = arr, _extends4));
            this.$emit('sku-prop-selected', {
                propValue: propValue,
                selectedProp: this.selectedProp,
                selectedSkuComb: this.selectedSkuComb
            });
        },
        onNumChange: function onNumChange(num) {
            this.selectedNum = num;
        },
        onPreviewImage: function onPreviewImage(indexImage) {
            var _this4 = this;

            var index = this.imageList.findIndex(function (image) {
                return image === indexImage;
            });
            var params = {
                index: index,
                imageList: this.imageList,
                indexImage: indexImage
            };
            this.$emit('open-preview', params);
            ImagePreview({
                images: this.imageList,
                startPosition: index,
                closeOnPopstate: true,
                onClose: function onClose() {
                    _this4.$emit('close-preview', params);
                }
            });
        },
        onOverLimit: function onOverLimit(data) {
            var action = data.action,
                limitType = data.limitType,
                quota = data.quota,
                quotaUsed = data.quotaUsed;
            var handleOverLimit = this.customStepperConfig.handleOverLimit;

            if (handleOverLimit) {
                handleOverLimit(data);
                return;
            }

            if (action === 'minus') {
                if (this.startSaleNum > 1) {
                    Toast(t('minusStartTip', this.startSaleNum));
                } else {
                    Toast(t('minusTip'));
                }
            } else if (action === 'plus') {
                if (limitType === QUOTA_LIMIT) {
                    if (quotaUsed > 0) {
                        Toast(t('quotaUsedTip', quota, quotaUsed));
                    } else {
                        Toast(t('quotaTip', quota));
                    }
                } else {
                    Toast(t('soldout'));
                }
            }
        },
        onStepperState: function onStepperState(data) {
            if (data.valid) {
                this.stepperError = null;
            } else {
                this.stepperError = _extends({}, data, {
                    action: 'plus'
                });
            }
        },
        onAddCart: function onAddCart() {
            this.onBuyOrAddCart('add-cart');
        },
        onBuy: function onBuy() {
            this.onBuyOrAddCart('buy-clicked');
        },
        onBuyOrAddCart: function onBuyOrAddCart(type) {
            // 有信息表示该sku根本不符合购买条件
            if (this.stepperError) {
                return this.onOverLimit(this.stepperError);
            }

            var error = this.validateSku();

            if (error) {
                Toast(error);
            } else {
                this.$emit(type, this.getSkuData());
            }
        },
        // @exposed-api
        getSkuData: function getSkuData() {
            return {
                goodsId: this.goodsId,
                selectedNum: this.selectedNum,
                selectedSkuComb: this.selectedSkuComb,
                messages: this.getSkuMessages(),
                cartMessages: this.getSkuCartMessages()
            };
        }
    },
    render: function render() {
        var _this5 = this;

        var h = arguments[0];

        if (this.isSkuEmpty) {
            return;
        }

        var sku = this.sku,
            goods = this.goods,
            price = this.price,
            originPrice = this.originPrice,
            skuEventBus = this.skuEventBus,
            selectedSku = this.selectedSku,
            selectedProp = this.selectedProp,
            selectedNum = this.selectedNum,
            stepperTitle = this.stepperTitle,
            selectedSkuComb = this.selectedSkuComb;
        var slotsProps = {
            price: price,
            originPrice: originPrice,
            selectedNum: selectedNum,
            skuEventBus: skuEventBus,
            selectedSku: selectedSku,
            selectedSkuComb: selectedSkuComb
        };

        var slots = function slots(name) {
            return _this5.slots(name, slotsProps);
        };

        var Header = slots('sku-header') || h(SkuHeader, {
            "attrs": {
                "sku": sku,
                "goods": goods,
                "skuEventBus": skuEventBus,
                "selectedSku": selectedSku
            }
        }, [slots('sku-header-price') || h("div", {
            "class": "van-sku__goods-price"
        }, [h("span", {
            "class": "van-sku__price-symbol"
        }, ["\uFFE5"]), h("span", {
            "class": "van-sku__price-num"
        }, [price]), this.priceTag && h("span", {
            "class": "van-sku__price-tag"
        }, [this.priceTag])]), slots('sku-header-origin-price') || originPrice && h(SkuHeaderItem, [t('originPrice'), " \uFFE5", originPrice]), !this.hideStock && h(SkuHeaderItem, [h("span", {
            "class": "van-sku__stock"
        }, [this.stockText])]), this.hasSkuOrAttr && !this.hideSelectedText && h(SkuHeaderItem, [this.selectedText]), slots('sku-header-extra')]);
        var Group = slots('sku-group') || this.hasSkuOrAttr && h("div", {
            "class": this.skuGroupClass
        }, [this.skuTree.map(function (skuTreeItem) {
            return h(SkuRow, {
                "attrs": {
                    "skuRow": skuTreeItem
                }
            }, [skuTreeItem.v.map(function (skuValue) {
                return h(SkuRowItem, {
                    "attrs": {
                        "skuList": sku.list,
                        "skuValue": skuValue,
                        "selectedSku": selectedSku,
                        "skuEventBus": skuEventBus,
                        "skuKeyStr": skuTreeItem.k_s
                    }
                });
            })]);
        }), this.propList.map(function (skuTreeItem) {
            return h(SkuRow, {
                "attrs": {
                    "skuRow": skuTreeItem
                }
            }, [skuTreeItem.v.map(function (skuValue) {
                return h(SkuRowPropItem, {
                    "attrs": {
                        "skuValue": skuValue,
                        "skuKeyStr": skuTreeItem.k_id + '',
                        "selectedProp": selectedProp,
                        "skuEventBus": skuEventBus,
                        "multiple": skuTreeItem.is_multiple
                    }
                });
            })]);
        })]);
        var Stepper = slots('sku-stepper') || h(SkuStepper, {
            "ref": "skuStepper",
            "attrs": {
                "stock": this.stock,
                "quota": this.quota,
                "quotaUsed": this.quotaUsed,
                "startSaleNum": this.startSaleNum,
                "skuEventBus": skuEventBus,
                "selectedNum": selectedNum,
                "selectedSku": selectedSku,
                "stepperTitle": stepperTitle,
                "skuStockNum": sku.stock_num,
                "disableStepperInput": this.disableStepperInput,
                "customStepperConfig": this.customStepperConfig,
                "hideQuotaText": this.hideQuotaText
            },
            "on": {
                "change": function change(event) {
                    _this5.$emit('stepper-change', event);
                }
            }
        });
        var Messages = slots('sku-messages') || h(SkuMessages, {
            "ref": "skuMessages",
            "attrs": {
                "goodsId": this.goodsId,
                "messageConfig": this.messageConfig,
                "messages": sku.messages
            }
        });
        var Actions = slots('sku-actions') || h(SkuActions, {
            "attrs": {
                "buyText": this.buyText,
                "skuEventBus": skuEventBus,
                "addCartText": this.addCartText,
                "showAddCartBtn": this.showAddCartBtn
            }
        });
        return h(Popup, {
            "attrs": {
                "round": true,
                "closeable": true,
                "position": "bottom",
                "getContainer": this.getContainer,
                "closeOnClickOverlay": this.closeOnClickOverlay,
                "safeAreaInsetBottom": this.safeAreaInsetBottom
            },
            "class": "van-sku-container",
            "model": {
                value: _this5.show,
                callback: function callback($$v) {
                    _this5.show = $$v;
                }
            }
        }, [Header, h("div", {
            "class": "van-sku-body",
            "style": this.bodyStyle
        }, [slots('sku-body-top'), Group, slots('extra-sku-group'), Stepper, Messages]), Actions]);
    }
});